import hashlib
import time
import logging
from datetime import datetime

from persistent import Persistent
from persistent.mapping import PersistentMapping
from zope.interface import implements
from zope.interface import Interface
from pyramid.security import Authenticated
from pyramid.security import Allow
from pyramid.security import Everyone
from pyramid.security import has_permission

from ampersands.core import vocabulary

log = logging.getLogger('ampersands')

DEFAULT_URI = 'sqlite:site.db'


class Ampersands(object):
    """
    """

    def __init__(self):
        """
        """
        self.__name__ = ''
        self.__parent__ = None
        self._contents = {}
        self._store = None
        self._zodb = None

    def __setitem__(self, name, item):
        self._contents[name] = item
        self._contents[name].__name__ = name
        self._contents[name].__parent__ = self

    def __getitem__(self, name):
        return self._contents[name]


class ICollections(Interface):
    pass


class Collections(PersistentMapping):
    implements(ICollections)

    __acl__ = [
        (Allow, Authenticated, 'add'),
        ]

    def __init__(self, name, parent, *args, **kwargs):
        self.__name__ = name
        super(PersistentMapping, self).__init__(*args, **kwargs)

    def new(self, owner):
        collection = Collection(self)
        self[collection.__name__] = collection
        collection.__acl__.append((Allow, owner, "edit"))
        collection.__acl__.append((Allow, owner, "view"))
        collection.__acl__.append((Allow, owner, "register"))
        return collection

    def getCollections(self, request):
        for collection in self.values():
            if has_permission("view", collection, request):
                yield collection

    def __setitem__(self, name, item):
        super(PersistentMapping, self).__setitem__(name, item)
        self._p_changed = True

    def __getitem__(self, name):
        item = PersistentMapping.__getitem__(self, name)
        item._v_parent = self
        return item


class ICollection(Interface):
    pass


class Collection(Persistent):
    """Represents a single data collection in ANDS.

    :attribute data: the contents of the forms that have been
       completed so far
    :attribute _formid: the last completed form id.
    :attribute _registered: is this object currently registered with ANDS.
    """
    implements(ICollection)

    def __init__(self, parent, *args, **kwargs):
        self.__acl__ = []
        self.data = PersistentMapping(*args, **kwargs)
        self.data['dateAccessioned'] = datetime.now()
        self.__name__ = hashlib.sha1(str(time.time())).hexdigest()
        self.data['identifier'] = self.__name__
        self.forms = []
        self._formid = "basic"
        self.__parent__ = parent
        self._registered = False

    def getTitle(self):
        """Return the current title of the collection, or untitled if
        it isn't defined.
        """
        if "title" in self.data.get("basic", {}):
            return self.data["basic"].get("title", "")
        return "(untitled)"

    def saveForm(self, formid, data):
        """Represents a single data collection in ANDS.

        :attribute formid: set the current form id.
        """
        self.data['dateModified'] = datetime.now()
        self.forms.append(formid)
        self.data[formid] = data

    def setForm(self, formid):
        """Represents a single data collection in ANDS.

        :attribute formid: set the current form id.
        """
        self._formid = formid

    def getForm(self):
        """Get the current formid
        """
        return self._formid

    def listForms(self):
        return self.forms

    def register(self):
        self._registered = True
        self.__acl__.append((Allow, Everyone, "view"))

    def delete(self):
        del self.__parent__[self.__name__]

    def getData(self, formid):
        data = self.data.get(formid, {}).copy()
        if not data:
            return data
        if formid == "basic":
            if "subjects" in data:
                for2008 = dict([x for x in vocabulary.for2008list()])
                for s in data['subjects']:
                    s['label'] = for2008.get(s['value'], '')
        return data

    def items(self):
        return self.data.items()


def appmaker(zodb_root):
    if not 'app_root' in zodb_root:
        app_root = Ampersands()
        zodb_root['app_root'] = app_root

        collections = Collections('collections', app_root)
        app_root['collections'] = collections

        import transaction
        transaction.commit()
    return zodb_root['app_root']
